package com.dou.sample.opengl_project.gl2;

import android.content.Context;
import android.opengl.GLSurfaceView;

import com.dou.sample.opengl_project.R;
import com.dou.sample.opengl_project.utls.ShaderHelper;
import com.dou.sample.opengl_project.utls.TextResourceReader;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import static android.opengl.GLES20.GL_FLOAT;
import static android.opengl.GLES20.GL_LINES;
import static android.opengl.GLES20.GL_POINTS;
import static android.opengl.GLES20.GL_TRIANGLE_FAN;
import static android.opengl.GLES20.glEnableVertexAttribArray;
import static android.opengl.GLES20.glGetAttribLocation;
import static android.opengl.GLES20.glGetUniformLocation;
import static android.opengl.GLES20.glUniformMatrix4fv;
import static android.opengl.GLES20.glUseProgram;
import static android.opengl.GLES20.glVertexAttribPointer;
import static android.opengl.Matrix.orthoM;

/**
 * Created by Dou on 2018/1/15.
 */

public class ReviewShaderRender implements GLSurfaceView.Renderer {

    private static final String A_POSITION = "a_Position";
    int aPositionLocation;

    private static final String U_COLOR = "u_Color";
    int uColorLocation;

    private static final String A_COLOR = "a_Color";
    int aColorLocation;

    private static final String U_MATRIX = "u_Matrix";
    int uMatrixLocation;
    final float[] projectionMatrix = new float[16];

    Context context;

    FloatBuffer vertexBuffer;

    int programId;

    float[] tableVertexs = {
            0,0,1,1,1,
            -0.5f, -0.8f, 0.3f, 0.3f, 0.3f,
            0.5f, -.8f,0.3f, 0.3f, 0.3f,
            .5f,.8f,0.3f, 0.3f, 0.3f,
            -.5f, .8f,0.3f, 0.3f, 0.3f,
            -.5f, -.8f,0.3f, 0.3f, 0.3f,

            -0.5f, 0,1,0,0,
            0.5f, 0,1,0,0,

            0, -0.5f,0,0,1,
            0, 0.5f,1,0,0
    };

    public ReviewShaderRender(Context context){
        this.context = context;

        vertexBuffer = ByteBuffer.allocateDirect(tableVertexs.length * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();
        vertexBuffer.put(tableVertexs);
        vertexBuffer.position(0);
    }

    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        gl.glClearColor(0, 0, 0, 0);

        String vertexShaderString = TextResourceReader.readTextFileFromResource(context, R.raw.review_vertex_shader);
        String fragmentShaderString = TextResourceReader.readTextFileFromResource(context, R.raw.review_fragment_shader);

        int vertexShaderId = ShaderHelper.compileVertexShader(vertexShaderString);
        int fragmentShaderId = ShaderHelper.compileFragmentShader(fragmentShaderString);

        programId = ShaderHelper.linkProgram(vertexShaderId, fragmentShaderId);
        glUseProgram(programId);

        aPositionLocation = glGetAttribLocation(programId, A_POSITION);
        uColorLocation = glGetUniformLocation(programId, U_COLOR);
        aColorLocation = glGetAttribLocation(programId, A_COLOR);
        uMatrixLocation = glGetUniformLocation(programId, U_MATRIX);

        vertexBuffer.position(0);
        glVertexAttribPointer(aPositionLocation, 2, GL_FLOAT, false, 5 * 4, vertexBuffer);
        glEnableVertexAttribArray(aPositionLocation);

        vertexBuffer.position(2);
        glVertexAttribPointer(aColorLocation, 3, GL_FLOAT, false, 5 * 4, vertexBuffer);
        glEnableVertexAttribArray(aColorLocation);
    }

    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
            gl.glViewport(0, 0, width, height);

            float aspectRatio = width > height ?
                    (float)width / (float)height :
                    (float)height / (float)width;

            if (width > height){
                // landscape
                orthoM(projectionMatrix, 0, -aspectRatio, aspectRatio, -1f, 1f, -1f, 1f);
            } else {
                // protraint
                orthoM(projectionMatrix, 0, -1, 1, -aspectRatio, aspectRatio, -1f, 1f);
            }
    }

    @Override
    public void onDrawFrame(GL10 gl) {
            gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
            glUniformMatrix4fv(uMatrixLocation, 1, false, projectionMatrix, 0);

            gl.glDrawArrays(GL_TRIANGLE_FAN, 0, 6);

            gl.glDrawArrays(GL_LINES, 6, 2);

            gl.glDrawArrays(GL_POINTS, 8, 1);
            gl.glDrawArrays(GL_POINTS, 9, 1);
    }
}
